#include "cliect.h"
#include <thread>
#include "led_test.h"
#include "usart.h"

char SERVER_IP[30] = "169.254.252.201";

Cliect::Cliect(QObject *parent) : QObject(parent)
{
    //init_client();
    std::thread([&]{
        recv_data();
    }).detach();

}

void *Cliect::recv_data()
{
    socketfd = socket(AF_INET, SOCK_STREAM, 0);
    if(socketfd < 0)
    {
        perror("socket fail\n");
        return NULL;
    }

    struct sockaddr_in seraddr;
    memset(&seraddr, 0, sizeof(seraddr));

    seraddr.sin_family      = AF_INET;
    seraddr.sin_port        = htons(PORT_TCP);
    seraddr.sin_addr.s_addr = inet_addr(SERVER_IP);
    int ret = ::connect(socketfd, (struct sockaddr *)&seraddr,sizeof(struct sockaddr));
    if(ret < 0)
    {
        perror("connect fail\n");
        return NULL;
    }
qDebug() << "connect ok";
    int size = 0;
    Package_t pack;
    while(1)
    {
        memset(&pack, 0, sizeof(pack));
        size = read(socketfd, &pack, sizeof(pack));
        if(size < 0)
        {
            perror("read fail\n");
            continue;
        }
        else if(size == 0)
        {
            printf("disconnect\n");
            break;
        }
        else
        {
            welog_debug("cmd = %d\n", pack.cmd);
            switch (pack.cmd)
            {
                case GET:
                {
                    download_file(pack.data);
                    break;
                }
                case SINGLE:
                {
                    printf("%s\n", pack.data);
                    emit sigCmd(pack.data);
                    break;
                }
                default:
                    welog_debug("others\n");
                    break;
            }

        }

    }
    close(socketfd);
    return NULL;
}

void Cliect::send_file(const char *file, std::string path)
{
    int  fd = open(file, O_RDWR);
    if(fd < 0)
    {
        perror("open fail\n");
        welog_debug("上传失败：文件不存在\n");
        return ;
    }

    //获取文件大小
    off_t size = lseek(fd, 0, SEEK_END);
    if(size <= 0)
    {
        welog_debug("上传失败：too small\n");
        close(fd);
        return ;
    }

    Package_t pack;
    memset(&pack, 0, sizeof(pack));
    pack.cmd = POST;

    cJSON *root = cJSON_CreateObject();
    cJSON_AddItemToObject(root,"file",cJSON_CreateString(file));
    cJSON_AddItemToObject(root,"size",cJSON_CreateNumber(size));
    cJSON_AddItemToObject(root,"path",cJSON_CreateString(path.c_str()));
    char *json_data = cJSON_Print(root);
    sprintf(pack.data, "%s", json_data);
    cJSON_Delete(root);

    write(socketfd, &pack, sizeof(pack));

    lseek(fd, 0, SEEK_SET);

    int ret = 0;
    long total = 0;
    char buf[1024] = {0};
    while(1)
    {
        memset(buf, 0, sizeof(buf));
        ret = read(fd,buf,1024);
        total += ret;
        if(ret < 0)
        {
            perror("读取失败\n");
            break;
        }
        else if(ret >= 0)
        {
            //welog_debug("progress = %ld%%\n", total*100/size);
            ret = write(socketfd, buf, ret);
            if(ret <= 0)
            {
                welog_debug("send fail\n");
                break;
            }
        }
        if(total>=size)
            break;
    }
    close(fd);
    qDebug() << "end";
}

void Cliect::download_file(char *data)
{
    //welog_debug("data = %s\n", data);
    cJSON *root = cJSON_Parse(data);
    if(root == NULL)
    {
        printf("get root fail!!!\n");
        return ;
    }

    char *path = cJSON_GetObjectItem(root,"file")->valuestring;
    long size = cJSON_GetObjectItem(root,"size")->valueint;
    if(path == NULL)
    {
        welog_debug("empty\n");
        cJSON_Delete(root);
        return ;
    }

    welog_debug("path = %s\n", path);
    int  fd = open(path, O_RDWR|O_CREAT, 666);
    if(fd < 0)
    {
        perror("open fail\n");
        return ;
    }
    cJSON_Delete(root);

    //获取文件大小
    int total=0;
    if(size <= 0)
    {
        welog_debug("下载失败\n");
        return ;
    }
    //welog_debug("size = %ld\n", size);
    char buf[1024] = {0};

    while(1)
    {
        memset(buf, 0, sizeof(buf));
        int ret = read(socketfd, buf, sizeof(buf));
        if(ret <= 0)
        {
            close(socketfd);
            break;
        }
        else
        {
            write(fd, buf, ret);
            total += ret;
            //printf("progress = %ld%%\n", total*100/size);
            if(total>=size)
            {
                welog_debug("end\n");
                break;
            }
        }
    }

    close(fd);

    system("./mplayer tts_sample.wav");
}

void Cliect::Send_Msg(Package_t pack)
{
    int size = write(socketfd, &pack, sizeof(pack));
    if(size > 0)
    {
        //welog_debug("send success\n");
    }
    else
        welog_debug("fail\n");
    return ;
}
